package cn.com.ccxe.core.search;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.NIOFSDirectory;
import org.apache.lucene.util.NumericUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wltea.analyzer.lucene.IKQueryParser;

import cn.com.ccxe.core.crawl.MonitorField;
import cn.com.ccxe.core.entity.Article;
import cn.com.ccxe.core.entity.ArticlePaging;
import cn.com.ccxe.core.util.Configurations;

public class FullTextSearch {

	static String DIRECTORY_PATH = Configurations.getString("index.path", "/directory");
	private static Directory directory;
	final static int TOP_DOCS_SIZE = 1000;
	final Logger logger = LoggerFactory.getLogger(FullTextSearch.class);
	private TopDocs topDocs;

	public FullTextSearch() {
		File directoryHome = new File(DIRECTORY_PATH);
		try {
			directory = new NIOFSDirectory(directoryHome);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private BooleanQuery parseQuery(SearchTerm term) throws IOException {
		
		BooleanQuery booleanQuery = new BooleanQuery();

		//是否搜索正文，1为搜索，0反之，默认为1。
		Query titleQuery = IKQueryParser.parse(MonitorField.TITLE.name(), term.getKeyword());
		if(term.getIsSearchContent() == 1) {
			//标题不一定出现关键字
			booleanQuery.add(titleQuery,Occur.SHOULD);
			Query contentQuery = IKQueryParser.parse(MonitorField.CONTENT.name(), term.getKeyword());
			//正文不一定出现关键字
			booleanQuery.add(contentQuery,Occur.MUST);
		} else {
			//标题必须出现关键字
			booleanQuery.add(titleQuery,Occur.MUST);
		}
		
		//时间
		Long min = Long.valueOf(term.getBeginDate());
		Long max = Long.valueOf(term.getEndDate());
		Query releaseDateQuery = NumericRangeQuery.newLongRange(MonitorField.RELEASE_DATE.name(),min, max,true, true);
		booleanQuery.add(releaseDateQuery, Occur.MUST);

		return booleanQuery;
	}
	
	public ArticlePaging search(SearchTerm term,int startIndex, int endIndex)
			throws IOException, CorruptIndexException {
		
		// search 
		IndexSearcher isearcher = new IndexSearcher(directory);
		
		Query query = parseQuery(term);

		SortField sortField = new SortField(MonitorField.RELEASE_DATE.name(),SortField.LONG,true);
		Sort sort = new Sort(sortField);
		
		topDocs = isearcher.search(query, null, TOP_DOCS_SIZE, sort);
		ScoreDoc[] scoreDocs = topDocs.scoreDocs;
		
		int size = endIndex - startIndex;
		List<Article> list = new ArrayList<Article>(size);
		for (int i = startIndex; i < endIndex && i < topDocs.totalHits; i++) {
			Document targetDoc = isearcher.doc(scoreDocs[i].doc);
			Article article = buildArticle(targetDoc);
			list.add(article);
		}
		ArticlePaging paging = new ArticlePaging();
		paging.setTotal(topDocs.totalHits);
		paging.setArticles(list);
		return paging;
	}

	private Article buildArticle(Document targetDoc) {

		Article article = new Article();
		String title = targetDoc.get(MonitorField.TITLE.name());
		if ("".equals(title)) {
			article.setTitle("无标题");
		}
		article.setTitle(title);
		
		article.setModuleId(NumericUtils.prefixCodedToInt(targetDoc.get(MonitorField.MODULE_ID.name())));
		article.setUrl(targetDoc.get(MonitorField.URL.name()));
		Long releaseDate = NumericUtils.prefixCodedToLong(targetDoc.get(MonitorField.RELEASE_DATE.name()));
		article.setReleaseDate(String.valueOf(releaseDate));
		return article;
		
	}

}
